package redis

import (
	"context"
	"g_group-buy-market/internal/pkg/config"
	"github.com/redis/go-redis/v9"
	"log"
	"time"
)

// RedisClient redis客户端
type RedisClient struct {
	client *redis.Client
	ctx    context.Context
}

func NewRedisClient(ctx context.Context, cfg *config.Config) *RedisClient {
	redisOpt := &redis.Options{
		Addr:         cfg.Redis.Addr,
		Password:     cfg.Redis.Password, // no password set
		DB:           cfg.Redis.Database, // use default DB
		PoolSize:     cfg.Redis.PoolSize,
		MinIdleConns: cfg.Redis.MinIdleSize,
		DialTimeout:  time.Duration(cfg.Redis.IdleTimeout) * time.Millisecond, //redis的单位为纳秒
		ReadTimeout:  time.Duration(cfg.Redis.ReadTimeout) * time.Millisecond,
		WriteTimeout: time.Duration(cfg.Redis.WriteTimeout) * time.Millisecond,
	}
	client := redis.NewClient(redisOpt)
	result, err := client.Ping(ctx).Result()
	if err != nil {
		panic("redis connect error: " + err.Error())
	}
	log.Println("redis ping result: " + result)
	return &RedisClient{client: client, ctx: ctx}
}

// 1. 字符串操作

// Set 设置键值对
func (r *RedisClient) Set(key string, value interface{}, expiration time.Duration) error {
	return r.client.Set(r.ctx, key, value, expiration).Err()
}

// Get 获取键值
func (r *RedisClient) Get(key string) (string, error) {
	return r.client.Get(r.ctx, key).Result()
}

// Delete 删除键
func (r *RedisClient) Delete(key string) error {
	return r.client.Del(r.ctx, key).Err()
}

// 2. 哈希操作

// HSet 设置哈希字段值
func (r *RedisClient) HSet(key string, field string, value interface{}) error {
	return r.client.HSet(r.ctx, key, field, value).Err()
}

// HGet 获取哈希字段值
func (r *RedisClient) HGet(key string, field string) (string, error) {
	return r.client.HGet(r.ctx, key, field).Result()
}

// HDel 删除哈希字段
func (r *RedisClient) HDel(key string, field string) error {
	return r.client.HDel(r.ctx, key, field).Err()
}

// 3. 列表操作

// LPush 列表左侧插入
func (r *RedisClient) LPush(key string, values ...interface{}) error {
	return r.client.LPush(r.ctx, key, values...).Err()
}

// RPop 列表右侧弹出
func (r *RedisClient) RPop(key string) (string, error) {
	return r.client.RPop(r.ctx, key).Result()
}

// 4. 集合操作

// SAdd 添加集合成员
func (r *RedisClient) SAdd(key string, members ...interface{}) error {
	return r.client.SAdd(r.ctx, key, members...).Err()
}

// SMembers 获取集合所有成员
func (r *RedisClient) SMembers(key string) ([]string, error) {
	return r.client.SMembers(r.ctx, key).Result()
}

// 5. 有序集合操作

// ZAdd 添加有序集合成员
func (r *RedisClient) ZAdd(key string, members ...redis.Z) error {
	return r.client.ZAdd(r.ctx, key, members...).Err()
}

// ZRange 获取有序集合成员
func (r *RedisClient) ZRange(key string, start, stop int64) ([]string, error) {
	return r.client.ZRange(r.ctx, key, start, stop).Result()
}

// 6. 通用操作

// Expire 设置过期时间
func (r *RedisClient) Expire(key string, expiration time.Duration) error {
	return r.client.Expire(r.ctx, key, expiration).Err()
}

// Exists 检查键是否存在
func (r *RedisClient) Exists(key string) (bool, error) {
	result, err := r.client.Exists(r.ctx, key).Result()
	return result > 0, err
}

// Close 关闭连接
func (r *RedisClient) Close() error {
	return r.client.Close()
}

// GetRedisService 直接引用
func (r *RedisClient) GetRedisService() *redis.Client {
	return r.client
}
